<script lang="jsx">
import { isVNode, withDirectives } from 'vue'
import { isArray } from '@vue/shared'
import DescItem from './item.vue'

export default {
  name: 'Desc',
  props: {
    data: Object,
    // 分成多少列，默认为1。默认span也是1，所以默认每行只有一个字段
    column: {
      type: Number,
      default: 1,
    },
    // label和value是否在同一行
    inline: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, { slots }) {
    function flattedChildren(children) {
      const vNodes = isArray(children) ? children : [children]
      const result = []
      vNodes.forEach((child) => {
        var _a
        if (isArray(child)) {
          result.push(...flattedChildren(child))
        } else if (isVNode(child) && isArray(child.children)) {
          result.push(...flattedChildren(child.children))
        } else {
          result.push(child)
          if (
            isVNode(child) &&
            ((_a = child.component) == null ? void 0 : _a.subTree)
          ) {
            result.push(...flattedChildren(child.component.subTree))
          }
        }
      })
      return result
    }

    function getRows() {
      const rows = [[]]
      const vnodes = slots.default()
      console.log(vnodes)
      const descItems = flattedChildren(vnodes).filter(
        (node) => node.type?.name === 'DescItem'
      )

      let spanSum = 0
      descItems.forEach((item) => {
        const span = item.props?.span || 1
        spanSum += span
        if (spanSum > props.column) {
          rows.push([])
          spanSum = span
        }
        const arr = rows[rows.length - 1]
        arr.push(item)
      })
      return rows
    }

    return {
      getRows,
    }
  },
  render() {
    const rows = this.getRows()
    const inline = this.inline
    const data = this.data
    return (
      <div class="desc">
        {rows.map((row) => (
          <div class="desc-row">
            {row.map((cell) => {
              const directives = (cell?.dirs || []).map((dire) => {
                const { dir, arg, modifiers, value } = dire
                return [dir, value, arg, modifiers]
              })

              return withDirectives(
                <DescItem inline={inline} data={data} {...cell.props}>
                  {{
                    label: cell.children?.label ?? null,
                    default: cell.children?.default ?? null,
                  }}
                </DescItem>,
                directives
              )
            })}
          </div>
        ))}
      </div>
    )
  },
}
</script>

<style lang="scss" scoped>
.desc {
  font-size: 13px;
  .desc-row {
    display: flex;
    &:first-child {
      .desc-label,
      .desc-value {
        margin-top: 0;
      }
    }
  }
}
</style>
